package com.edu.base.rest;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.edu.base.common.ParamsUtil;
import com.edu.base.common.SystemService;
import com.edu.base.common.utils.MD5Util;
import com.edu.base.common.vo.LoginRegisterEnum;
import com.edu.base.rest.service.AdminService;
import com.edu.base.rest.service.AppTokenService;
import com.edu.base.rest.service.RestBaseService;
import com.edu.base.ums.countrycode.domain.ClsMemberCountrycode;
import com.edu.base.ums.countrycode.service.IClsMemberCountrycodeService;
import com.edu.base.ums.member.domain.ClsMember;
import com.edu.base.ums.member.mapper.ClsMemberMapper;
import com.edu.base.ums.member.service.IClsMemberService;
import com.edu.common.systemSetup.service.ISystemSetupService;
import com.edu.utils.UserContextUtil;
import com.google.common.collect.Maps;
import com.ruoyi.common.config.SmsConfig;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.model.AppLoginUser;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.utils.MessageUtils;
import com.ruoyi.common.utils.UUIDUtils;
import com.ruoyi.common.utils.bean.BeanUtils;
import com.ruoyi.common.utils.bean.SmsResult;
import com.ruoyi.common.utils.sms.HuaweiSmsSender;
import com.ruoyi.common.utils.sms.aliyunSmsUtils;
import com.ruoyi.framework.manager.AsyncManager;
import com.ruoyi.framework.manager.factory.AsyncFactory;
import com.ruoyi.framework.web.service.SysLoginService;
import com.ruoyi.system.service.ISysNoticeService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;
import springfox.documentation.annotations.ApiIgnore;

import javax.servlet.http.HttpServletRequest;
import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * 获得公告接口
 *
 * @author lf
 * @version 2020-03-09
 */

@Api(tags = "1、登录注册")
@RestController
@RequestMapping("/api/appUser")
public class AppBackUserLoginController extends BaseController {

  @Autowired
  private HttpServletRequest request;

  @Autowired
  private RedisCache redisCache;


  @Autowired
  private RestBaseService restBaseService;

  @Autowired
  private ClsMemberMapper clsMemberMapper;

  @Autowired
  private IClsMemberService clsMemberService;

  @Autowired
  private AdminService adminService;

  private final boolean ifVerfyCodeLoginToRegister = false;//是否验证码快捷登录时，不存在用户自动注册

  @Autowired
  private RedisTemplate<String, String> redisTemplate;

  @Autowired
  private SysLoginService sysLoginService;

  @Autowired
  private IClsMemberCountrycodeService clsMemberCountrycodeService;

  public final static String defautPhotoUrlTeacher = "http://langwen.oss-cn-beijing.aliyuncs.com/banckground/0a9e22ca6ed64867998173ab6b9c10f2.png";
  public final static String defautPhotoUrlStudent = "http://langwen.oss-cn-beijing.aliyuncs.com/banckground/a45a29d897374c60b21917c57e4bdf72.png";

  @Autowired
  private AppTokenService appTokenService;

  @Autowired
  private ISystemSetupService systemSetupService;

  /**
   * 手机号一键登录
   *
   * @param phone 电话号
   * @return
   */
  @GetMapping(value = "/phoneLogin")
  @ApiOperation(value = "1、手机号一键登录接口")
  @ApiImplicitParams({
      @ApiImplicitParam(name = "phone", value = "手机号码", required = true),
  })
  public AjaxResult phoneLogin(String phone) {
    Map<String, Object> dataMap = new HashMap<String, Object>();
    List<ClsMember> umslist = clsMemberMapper.selectClsMemberByPhone(phone);
    if (CollectionUtils.isEmpty(umslist) && !ifVerfyCodeLoginToRegister) {
      ClsMember clsMember = this.clsMemberService.insertClsMemberRyByPHone(phone);
      String token = appTokenService.createToken(clsMember);
      dataMap.put("token", token);
      appTokenService.refreshAppToken(clsMember);
      AsyncManager.me().execute(AsyncFactory.recordAppLogininfor(clsMember.getId(), Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success")));
      return AjaxResult.success(dataMap);
    } else {
      ClsMember exist = umslist.get(0);
      if ("0".equals(exist.getStatus())) {
        AsyncManager.me().execute(AsyncFactory.recordAppLogininfor(exist.getId(), Constants.LOGIN_FAIL, MessageUtils.message("user.blocked")));
        return AjaxResult.success(LoginRegisterEnum.buildReturnMap(LoginRegisterEnum.USER_BE_FREEZE));
      }
      exist.setLoginTime(new Date());
      String token = appTokenService.createToken(exist);
      exist.setToken(token);
      appTokenService.refreshAppToken(exist);
      clsMemberService.updateClsMember(exist);
      dataMap.put("token", token);
      AsyncManager.me().execute(AsyncFactory.recordAppLogininfor(exist.getId(), Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success")));
      return AjaxResult.success(dataMap);
    }
  }

  @GetMapping(value = "/logOut")
  @ApiOperation("退出登录")
  @ApiImplicitParams({
      @ApiImplicitParam(name = "memberId", value = "会员id", required = true),
  })
  public AjaxResult logOut(String memberId) {
    appTokenService.deleteToken(memberId);
    return AjaxResult.success();
  }

  @GetMapping(value = "/logOff")
  @ApiOperation("注销用户")
  @ApiImplicitParams({
      @ApiImplicitParam(name = "memberId", value = "会员id", required = true),
  })
  public AjaxResult logOff(String memberId) {
    appTokenService.deleteToken(memberId);
    ClsMember clsMember = new ClsMember();
    clsMember.setId(memberId);
    clsMember.setStatus("0");//用户状态0：注销，1 正常
    clsMember.setBan("1"); //是的禁用
    clsMember.setBanTime(new Date());//禁用时间
    return toAjax(clsMemberService.changeClsMemberStatus(clsMember));

  }

  @GetMapping(value = "/sendCode")
  @ApiOperation("2、发送短信验证码")
  @ApiImplicitParams({
      @ApiImplicitParam(name = "phoneNumber", value = "手机号码", required = true),
  })
  public AjaxResult sendSms(String phoneNumber) {
    //发送短信验证码
    String code = com.ruoyi.common.utils.StringUtils.getRandomCode(6);
//    SmsResult result = aliyunSmsUtils.SendSms(phoneNumber);
    HuaweiSmsSender.sendVerificationCode(phoneNumber, code);

    redisTemplate.opsForValue().set("sms_" + phoneNumber + "_" + code, code, SmsConfig.getExpireTime(), TimeUnit.SECONDS);

    if ("OK".equals(code)) {
      //验证码缓存到redis中，有效期60s
//      redisTemplate.opsForValue().set("sms_" + phoneNumber + "_" + code, code, SmsConfig.getExpireTime(), TimeUnit.SECONDS);
//      return AjaxResult.success("验证码发送成功", result.getSendSmsResponse());
    } else {
//      return AjaxResult.success("验证码发送失败", result.getSendSmsResponse());
    }
    return AjaxResult.success();

  }

  @Autowired
  private ISysNoticeService sysNoticeService;

  @GetMapping(value = "/codeLogin")
  @ApiOperation("3、手机验证码登录/注册")
  @ApiImplicitParams({
      @ApiImplicitParam(name = "phone", value = "手机号码", required = true),
      @ApiImplicitParam(name = "code", value = "验证码", required = true),
      @ApiImplicitParam(name = "invicateCode", value = "邀请码", required = false),
  })
  public AjaxResult codeLogin(String phone, String code, String invicateCode) {
    //根据key查找value
    ClsMember clsMember = new ClsMember();
    AjaxResult ajaxResult = AjaxResult.success();
    //从缓存中获取验证码
    String rcode = redisTemplate.opsForValue().get("sms_" + phone + "_" + code);

    // TODO 测试用户，避免多次重复发送短信，上线后需要移除
//    if ("1".equals(code) && "16604131123".equals(phone)) {
//      rcode = code;
//    }
    if ("123456".equals(code) && Arrays.asList("17645542156", "17604023841", "18000000000").contains(phone)) {
      rcode = code;
    }

    if (StringUtils.isEmpty(rcode)) {//验证码过期失效
      return AjaxResult.error(JSON.toJSONString(LoginRegisterEnum.buildReturnMap(LoginRegisterEnum.CODE_LOSSE)));
    } else {
      if (code.equals(rcode)) {
        List<ClsMember> umslist = clsMemberService.selectClsMemberByPhone(phone);
        //用户已存在
        if (CollectionUtils.isNotEmpty(umslist)) {
          clsMember = umslist.get(0);
          if ("0".equals(clsMember.getStatus())) {
            AsyncManager.me().execute(AsyncFactory.recordAppLogininfor(clsMember.getId(), Constants.LOGIN_FAIL, MessageUtils.message("user.blocked")));
            return AjaxResult.success(LoginRegisterEnum.buildReturnMap(LoginRegisterEnum.USER_BE_FREEZE));
          } else {
            String token = appTokenService.createToken(clsMember);
//            ajaxResult.put("token", token);
            // 登录后直接返回完整的会员信息-附加token
            clsMember.setToken(token);
            ajaxResult.put("data", clsMember);
            AsyncManager.me().execute(AsyncFactory.recordAppLogininfor(clsMember.getId(), Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success")));
          }
          clsMemberService.updateClsMember(clsMember);//更新登录时间
        } else {//新增用户
          clsMember = builderClsMember(phone, invicateCode);
          String token = appTokenService.createToken(clsMember);
          int result = clsMemberService.insertClsMember(clsMember);
          if (result > 0) {
//            ajaxResult.put("token", token);
            clsMember.setToken(token);
            ajaxResult.put("data", clsMember);
            AsyncManager.me().execute(AsyncFactory.recordAppLogininfor(clsMember.getId(), Constants.LOGIN_SUCCESS, "注册成功"));
            AsyncManager.me().execute(clsMemberService.udateMemberScore(clsMember.getId(), phone, invicateCode));

          } else {
            AsyncManager.me().execute(AsyncFactory.recordAppLogininfor(clsMember.getId(), Constants.LOGIN_FAIL, MessageUtils.message("user.blocked")));
            return AjaxResult.success("注册失败");
          }
        }

        sysNoticeService.saveNotice(clsMember.getId(), "注册成功", "恭喜您，注册成功");
      } else {
        AsyncManager.me().execute(AsyncFactory.recordAppLogininfor(clsMember.getId(), Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.error")));
        return AjaxResult.success(LoginRegisterEnum.buildReturnMap(LoginRegisterEnum.VERIFYCODE_ERROR));
      }
    }

    return ajaxResult;
  }

  /**
   * 初始化会员基础信息
   *
   * @param phone
   * @return
   */
  public ClsMember builderClsMember(String phone, String inviteCode) {
    ClsMember clsMember = new ClsMember();
    clsMember.setId(UUIDUtils.getUUID());
    clsMember.setCreateDate(new Date());
    clsMember.setMemberType("2");
    clsMember.setBlance(0L);
    clsMember.setStatus("1");
    clsMember.setIntegration(0L);
    clsMember.setHighLevel(0L);
    clsMember.setGender("1");
    clsMember.setUserName(phone);
    clsMember.setNickName(phone);
    clsMember.setPassWord(MD5Util.string2MD5(phone));
    clsMember.setPhone(phone);
    clsMember.setLoginTime(new Date());
    return clsMember;
  }


  /**
   * 验证token是否过期
   */
  @GetMapping(value = "/validateToken")
  @ApiOperation("验证token是否过期")
  @ApiImplicitParams({
      @ApiImplicitParam(name = "token", value = "token令牌", required = true),
  })
  @ApiIgnore
  public AjaxResult validateToken(String token) {
    boolean verify = appTokenService.verify(token);
    return AjaxResult.success(verify);
  }


  /**
   * 账号密码登录
   */
  @PostMapping("/passwordLogin")
  @ApiOperation("账号密码登录接口")
  @ApiImplicitParams({
      @ApiImplicitParam(name = "username", value = "用户名"),
      @ApiImplicitParam(name = "phone", value = "手机号"),
      @ApiImplicitParam(name = "passWord", value = "密码"),
  })
  @ApiIgnore
  public AjaxResult passwordLogin(String username, String phone, String passWord) {
//    List<String> list = ParamsUtil.listAllParams(request);
//    if (!list.isEmpty()) {
//      list.remove("phone");
//      list.remove("username");
//      list.remove("passWord");
//      if (list.size() > 10) {
//        list = list.subList(0, 10);
//      }
//    }

    // 检验请求参数合法性
    if (StringUtils.isBlank(phone) && StringUtils.isBlank(username)) {
      return AjaxResult.error("账户不能为空");
    }
    if (StringUtils.isBlank(passWord)) {
      return AjaxResult.error("密码不能为空");
    }
    List<ClsMember> clslist = new ArrayList<>();
    if (StringUtils.isNotBlank(phone)) {
      clslist = clsMemberMapper.selectClsMemberByPhone(phone);
    } else if (StringUtils.isNotBlank(username)) {
      clslist = clsMemberMapper.selectClsMemberByUserName(username);
    }
    ClsMember exist = null;
    if (CollectionUtils.isEmpty(clslist)) {
      return AjaxResult.error(LoginRegisterEnum.USER_NOT_EXIST.getErrorMessage());
    } else {
      exist = clslist.get(0);
      if (StringUtils.isBlank(exist.getPassWord())) {
        return AjaxResult.error(LoginRegisterEnum.USER_NOT_SET_PASSWORD.getErrorMessage());
      } else {
        try {
          if (!SystemService.validatePassword(passWord, exist.getPassWord())) {
            return AjaxResult.error(LoginRegisterEnum.PASSWORD_NOT_CORECCT.getErrorMessage());
          } else if ("0".equals(exist.getStatus())) {
            return AjaxResult.error(LoginRegisterEnum.USER_BE_FREEZE.getErrorMessage());
          } else {
            exist.setLoginTime(new Date());
            clsMemberMapper.updateClsMember(exist);
          }
        } catch (Exception e) {
          return AjaxResult.error(e.getMessage());
        }
      }


    }

    AjaxResult ajaxResult = AjaxResult.success();
//    String msg = "";
//    String param = String.join("、", list);
//    if (StringUtils.isNotBlank(param)) {
//      msg += "参数列中的" + param + "等参数并未定义在参数列表中，为无效参数。";
//    }
//    if (StringUtils.isNotBlank(msg)) {
//      return AjaxResult.error(msg);
//    }

    String token = appTokenService.createToken(exist);
//            ajaxResult.put("token", token);
    // 登录后直接返回完整的会员信息-附加token
    exist.setToken(token);
    ajaxResult.put("data", exist);
    AsyncManager.me().execute(AsyncFactory.recordAppLogininfor(exist.getId(), Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success")));
    return ajaxResult;
  }


  /**
   * 获取国家代号(CountryCode)与区号
   *
   * @return
   */
  @GetMapping(value = "/getAllCountryCode")
  @ApiOperation("获取国家代号(CountryCode)与区号")
  public AjaxResult getAllCountryCode() {

    List<ClsMemberCountrycode> countyCodeList = redisCache.getCacheList("countryCode");
    if (CollectionUtils.isEmpty(countyCodeList)) {
      ClsMemberCountrycode clsMemberCountrycode = new ClsMemberCountrycode();
      clsMemberCountrycode.setDelFlag("0");
      countyCodeList = clsMemberCountrycodeService.selectClsMemberCountrycodeList(clsMemberCountrycode);
      redisCache.setCacheList("countryCode", countyCodeList);
    }

    return AjaxResult.success(countyCodeList);
  }


  @PostMapping("/codeLogin")
  @ApiOperation("手机验证码登录")
  @ApiImplicitParams({@ApiImplicitParam(name = "phone", value = "手机号", required = true),
      @ApiImplicitParam(name = "code", value = "验证码", required = true)
  })
  @ApiIgnore
  public AjaxResult register(String phone, String code) {
    List<String> list = ParamsUtil.listAllParams(request);
    if (!list.isEmpty()) {
      // 参数列中的parameter1、parameter2、parameter3等参数并未定义在参数列表中，为无效参数。
      list.remove("phone");
      list.remove("code");
      if (list.size() > 10) {
        list = list.subList(0, 10);
      }
    }
    Integer reslut = adminService.register(phone, code);
    if (reslut == 1) {
      //判断当前是否系统中存在，若存在则修改登录时间，若不存在则注册
      List<ClsMember> clslist = clsMemberMapper.selectClsMemberByPhone(phone);
      if (CollectionUtils.isEmpty(clslist)) {
        ClsMember clsMember = new ClsMember();
        clsMember.setStatus("1");
        clsMember.setMemberType("4");
        clsMember.setIntegration(0L);
        clsMember.setBlance(0L);
        clsMember.setSourceType("1");
        clsMember.setCreateTime(new Date());
        clsMember.setUserName(phone);
        clsMember.setPhone(phone);
        clsMember.setPassWord(SystemService.entryptPassword("123456"));//默认密码
        clsMember.setNickName(phone);
        clsMember.setIcon(defautPhotoUrlStudent);
        //clsMember.setTr(null);
        this.clsMemberMapper.insertClsMember(clsMember);
      } else {
        ClsMember exist = clslist.get(0);
        exist.setLoginTime(new Date());
        clsMemberMapper.updateClsMember(exist);
      }

      return AjaxResult.success();
    }

    String msg = "";
    String param = String.join("、", list);
    if (StringUtils.isNotBlank(param)) {
      msg += "参数列中的" + param + "等参数并未定义在参数列表中，为无效参数。";
    }
    if (StringUtils.isNotBlank(msg)) {
      return AjaxResult.error(msg);
    }
    return AjaxResult.error("验证码与手机号不匹配！");

  }


  /**
   * 描述：我的个人中心-验证登录密码接口
   *
   * @return
   * @request
   */
  @PostMapping("/checkingLoginPassword")
  @ApiOperation("我的个人中心-验证登录密码接口")
  @ApiImplicitParams({
      @ApiImplicitParam(name = "loginPassword", value = "密码", required = true),
      @ApiImplicitParam(name = "phone", value = "手机号码", required = true)
  })
  @ApiIgnore
  public AjaxResult checkingLoginPassword(String loginPassword, String phone) {
    List<String> list = ParamsUtil.listAllParams(request);
    if (!list.isEmpty()) {
      // 参数列中的parameter1、parameter2、parameter3等参数并未定义在参数列表中，为无效参数。
      list.remove("loginPassword");
      list.remove("phone");
      if (list.size() > 10) {
        list = list.subList(0, 10);
      }
    }
    Map<String, Object> dataMap = new HashMap<String, Object>();
    // 检验请求参数合法性
    if (StringUtils.isBlank(loginPassword)) {
      return AjaxResult.error("账户不能为空");
    }
    List<ClsMember> clslist = this.clsMemberMapper.selectClsMemberByPhone(phone);
    if (CollectionUtils.isEmpty(clslist)) {
      return AjaxResult.success(LoginRegisterEnum.buildReturnMap(LoginRegisterEnum.USER_NOT_EXIST));
    }
    try {
      if (SystemService.validatePassword(loginPassword, SystemService.entryptPassword(clslist.get(0).getPassWord())) &&
          StringUtils.isNotBlank(clslist.get(0).getPassWord())) {
        dataMap.put("loginPassword", "Success");
      } else {
        dataMap.put("loginPassword", "fail");
      }
    } catch (Exception e) {
      return AjaxResult.error(e.getMessage());
    }

    String msg = "";
    String param = String.join("、", list);
    if (StringUtils.isNotBlank(param)) {
      msg += "参数列中的" + param + "等参数并未定义在参数列表中，为无效参数。";
    }
    if (StringUtils.isNotBlank(msg)) {
      return AjaxResult.error(msg);

    }
    return AjaxResult.success(dataMap);
  }


  /**
   * https://www.jb51.net/article/94615.htm
   *
   * @throws
   * @title weChatLogin
   * @description 微信授权登录
   */
  @ApiOperation(value = "4、微信授权登录")
  @ApiImplicitParams({
      @ApiImplicitParam(paramType = "query", name = "code",
          value = "用户换取access_token的code，仅在ErrCode为0时有效",
          required = true, dataType = "String")
  })
  @GetMapping("/weChatLogin")
  public AjaxResult weChatLogin(@RequestParam String code) {
    return clsMemberService.weChatLogin(code);
  }


  /**
   * https://www.cnblogs.com/zwqh/p/11579275.html
   *
   * @throws
   * @title weChatLogin
   * @description 微信授权登录
   */
  @ApiOperation(value = "5、QQ授权登录")
  @ApiImplicitParams({
      @ApiImplicitParam(name = "code", value = "code"),
      @ApiImplicitParam(name = "state", value = "state")
  })
  @GetMapping("/qqLogin")
  public AjaxResult qqLogin(@RequestParam String code, @RequestParam String state) {
    return clsMemberService.qqLogin(code, state);
  }

  /**
   * https://www.cnblogs.com/chenhao-/p/7205207.html
   *
   * @param @param  code
   * @param @param  state
   * @param @return 参数
   * @return AjaxResult 返回类型
   * @throws
   * @Title: wbLogin
   * @Description: TODO(这里用一句话描述这个方法的作用)
   */
  @ApiIgnore
  @ApiOperation(value = "微博授权登录")
  @ApiImplicitParams({
      @ApiImplicitParam(name = "error_code", value = "error_code"),
      @ApiImplicitParam(name = "code", value = "code", required = true),
      @ApiImplicitParam(name = "state", value = "state", required = true)
  })
  @GetMapping("/wbLogin")
  public AjaxResult wbLogin(@RequestParam String error_code, @RequestParam String code, @RequestParam String state) {
    return clsMemberService.wbLogin(error_code, code, state);
  }


  /**
   * @Description： 第三方登录
   * @author: liujintao
   * @since: 2018年9月7日 上午10:15:12
   */

  @PostMapping("/thirdPartyLogin")
  @ApiOperation("第三方登录接口")
  @ApiImplicitParams({
      @ApiImplicitParam(name = "thirdType", value = "5:qq、6:微信、6:微博  苹果类型", required = true),
      @ApiImplicitParam(name = "thirdPartyId", value = "第三方类型的id", required = true),
      @ApiImplicitParam(name = "mustBindPhone", value = "是否绑定手机号，1：是，0：否")
  })
  @ApiIgnore
  public AjaxResult checkThirdPartyBinding(String thirdType, String thirdPartyId, String mustBindPhone) {
    List<String> list = ParamsUtil.listAllParams(request);
    if (!list.isEmpty()) {
      list.remove("thirdType");// qq、微信、微博 苹果类型
      list.remove("thirdPartyId");// 第三方类型的id
      list.remove("mustBindPhone");//// 如果没有绑定手机号时，是否直接注册新用户并登录，为1的时候表示是
      if (list.size() > 10) {
        list = list.subList(0, 10);
      }
    }

    try {
      Map<String, Object> dataMap = new HashMap<String, Object>();
      ClsMember user = this.clsMemberService.checkThirdPartyBindingUser(thirdType, thirdPartyId);// 校验第三方id是否绑定过用户
      String termId = request.getHeader("termId");
      if (user != null) {// 第三方id已绑定,直接登陆
        dataMap = clsMemberService.bindingLoginSetToken(user);
        dataMap.put("notBindingThirdPartyUser", "0");
      } else {
        if ("1".equals(mustBindPhone)) {// 此处去用第三方id新增一个app用户

        } else {
          dataMap.put("notBindingThirdPartyUser", "1");
        }

      }
      String msg = "";
      String param = String.join("、", list);
      if (StringUtils.isNotBlank(param)) {
        msg += "参数列中的" + param + "等参数并未定义在参数列表中，为无效参数。";
      }
      if (StringUtils.isNotBlank(msg)) {
        return AjaxResult.error(msg);
      }
      return AjaxResult.success(dataMap);
    } catch (Exception e) {
      logger.error("校验第三方id是否绑定过用户接口异常:", e);
      return AjaxResult.error("系统异常");
    }
  }

  /**
   * @Description： 第三方绑定手机号，或者说第三方绑定用户
   * @author: liujintao
   * @since: 2018年9月7日 上午10:15:42
   */
  @PostMapping(value = "/thirdPartyBinding")
  @ApiOperation("第三方绑定手机号，或者说第三方绑定用户")
  @ApiImplicitParams({
      @ApiImplicitParam(name = "phone", value = "手机号"),
      @ApiImplicitParam(name = "code", value = "第三方类型的id", required = true),
      @ApiImplicitParam(name = "thirdType", value = "绑定类型"),
      @ApiImplicitParam(name = "thirdPartyId", value = "第三方id"),
      @ApiImplicitParam(name = "password", value = "password"),
      @ApiImplicitParam(name = "nickName", value = "昵称"),
      @ApiImplicitParam(name = "icon", value = "第三方图像icon"),

  })
  @ApiIgnore
  public AjaxResult thirdPartyBinding(String phone, String code, String thirdType,
                                      String thirdPartyId, String password, String nickName, String icon) {
    List<String> list = ParamsUtil.listAllParams(request);
    if (!list.isEmpty()) {
      list.remove("phone");
      list.remove("code");
      list.remove("thirdType");
      list.remove("thirdPartyId");
      list.remove("password");
      list.remove("nickName");
      list.remove("icon");
      if (list.size() > 10) {
        list = list.subList(0, 10);
      }
    }

    Map<String, Object> dataMap = new HashMap<String, Object>();

    String termId = request.getHeader("termId");

    String codeStr = redisTemplate.opsForValue().get(phone);
    if (StringUtils.isBlank(codeStr)) {
      AjaxResult.error(JSON.toJSONString(LoginRegisterEnum.buildReturnMap(LoginRegisterEnum.CODE_LOSSE)));
    } else {
      if (!codeStr.equals(code)) {
        return AjaxResult.success(LoginRegisterEnum.buildReturnMap(LoginRegisterEnum.VERIFYCODE_ERROR));
      }
      // 需要先根据手机号判断这个手机号是否已经注册
      List<ClsMember> clsList = this.clsMemberMapper.selectClsMemberByPhone(phone);
      if (CollectionUtils.isEmpty(clsList)) {
        return AjaxResult.success(dataMap);
      } else if (CollectionUtils.isNotEmpty(clsList) && clsList != null) {
        ClsMember clsMember = clsList.get(0);
        String weixinOpenid = clsMember.getWeixinOpenid();
        String blogToken = clsMember.getBlogToken();
        String appleId = clsMember.getAppleId();
        String qqToken = clsMember.getQqToken();
        if (StringUtils.isEmpty(weixinOpenid) && StringUtils.isEmpty(blogToken) && StringUtils.isEmpty(appleId)
            && StringUtils.isEmpty(qqToken)) {
          ClsMember user = this.clsMemberService.userBindingThirdParty(thirdPartyId, phone, thirdType, password,
              nickName, icon);// 绑定或者注册绑定
          dataMap = clsMemberService.bindingLoginSetToken(user);
          Date date = new Date();
          if (date.equals(user.getCreateDate())) {
            dataMap.put("newUser", "1");
          }
          // JedisUtils.set(user.getId(), termId, 0);
          redisTemplate.opsForHash().put(String.valueOf(user.getId()), termId, String.valueOf(0));
          return AjaxResult.success(dataMap);
        } else {
          Map<String, Object> mo = Maps.newHashMap();
          mo.put("errorStatus", "2020");
          mo.put("errorMessage", "绑定失败，您的第三方已经绑定过别的手机号或者这个手机号已经绑定过其他的三方了！！！");
          return AjaxResult.success(mo);
        }
      }
    }
    return AjaxResult.success();
  }


  /**
   * 检测用户状态
   *
   * @param userName
   * @param
   * @param
   * @return
   */
  @PostMapping(value = "/checkingUserStatus")
  @ApiOperation("检测用户状态接口")
  @ApiImplicitParams({
      @ApiImplicitParam(name = "userName", value = "返回值（userStatus= {2:不存在、1:存在、0:禁用}", required = true),
  })
  public AjaxResult checkingUserStatus(String userName) {
    List<String> list = ParamsUtil.listAllParams(request);
    if (!list.isEmpty()) {
      list.remove("userName");
      if (list.size() > 10) {
        list = list.subList(0, 10);
      }
    }

    Map<String, Object> dataMap = new HashMap<String, Object>();
    List<ClsMember> clsMemberList = this.clsMemberMapper.selectClsMemberByUserName(userName);
    if (CollectionUtils.isEmpty(clsMemberList)) {
      dataMap.put("userStatus", "2");
    } else {
      ClsMember appuser = clsMemberList.get(0);
      if (appuser.getStatus().equals("1")) {
        dataMap.put("userStatus", "1");
      } else {
        dataMap.put("userStatus", "0");
      }
    }
    String msg = "";
    String param = String.join("、", list);
    if (StringUtils.isNotBlank(param)) {
      msg += "参数列中的" + param + "等参数并未定义在参数列表中，为无效参数。";
    }
    if (StringUtils.isNotBlank(msg)) {
      return AjaxResult.error(msg);
    }

    return AjaxResult.success(dataMap);
  }

  /**
   * 更换绑定手机号
   *
   * @param
   * @return
   */
  @PostMapping(value = "/updateBindingMobile")
  @ApiOperation("更换绑定手机号")
  @ApiImplicitParams({
      @ApiImplicitParam(name = "phone", value = "手机号"),
      @ApiImplicitParam(name = "code", value = "验证码"),
  })
  @ApiIgnore
  public AjaxResult updateBindingMobile(String phone, String code) {
    // 逻辑业务操作
    Map<String, Object> dataMap = new HashMap<String, Object>();
    try {

      List<ClsMember> umsMemberList = this.clsMemberMapper.selectClsMemberByPhone(phone);
      if (umsMemberList.get(0).getMemberType().equals("3")) {// 说明是教师角色，小需要通过手机号去系统用户表去查询
        if (CollectionUtils.isNotEmpty(umsMemberList)) {// 说明用户存在手机号已被注册
          return AjaxResult.success(LoginRegisterEnum.buildReturnMap(LoginRegisterEnum.PHONE_BE_REGISTER));
        }
      }
      // 通过手机号查询用户,查看该手机号是否已被注册
      if (CollectionUtils.isNotEmpty(umsMemberList)) {// 说明用户存在手机号已被注册
        return AjaxResult.success(LoginRegisterEnum.buildReturnMap(LoginRegisterEnum.PHONE_BE_REGISTER));
      }
      // 若手机号存在情况下,再判断验证码
      String codeStr = redisTemplate.opsForValue().get(phone);
      if (StringUtils.isBlank(codeStr)) {
        return AjaxResult
            .error(JSON.toJSONString(LoginRegisterEnum.buildReturnMap(LoginRegisterEnum.CODE_LOSSE)));
      } else {
        if (!codeStr.equals(code)) {
          return AjaxResult.error(
              JSON.toJSONString(LoginRegisterEnum.buildReturnMap(LoginRegisterEnum.VERIFYCODE_ERROR)));
        }
      }
    } catch (Exception e) {
      logger.error("更换绑定手机号调用异常:", e);
      return AjaxResult.error("更换绑定手机号调用异常");
    }
    return AjaxResult.success(dataMap);
  }

  @PostMapping("/phone/edit")
  public AjaxResult editPhone(@RequestBody JSONObject data) {
    // 获取当前登录用户
    AppLoginUser user = UserContextUtil.currentUser();

    // 按手机号获取用户信息
    List<ClsMember> members = clsMemberMapper.selectList(new LambdaQueryWrapper<ClsMember>()
            .eq(ClsMember::getStatus, 1)
            .eq(ClsMember::getPhone, data.getString("phone"))
            .ne(ClsMember::getId, user.getId())
    );

    if (!members.isEmpty()) return AjaxResult.error("手机号已被注册");

    String code = redisTemplate.opsForValue().get("sms_" + user.getPhone() + "_" + data.getString("code"));

    if (StringUtils.isBlank(code)) return AjaxResult.error("验证码错误");
    if (user.getPhone().equals(data.getString("phone"))) return AjaxResult.error("手机号码不能和原号码一致");

    // 变更手机号
    clsMemberMapper.update(null, new LambdaUpdateWrapper<ClsMember>()
            .eq(ClsMember::getId, user.getId())
            .set(ClsMember::getPhone, data.getString("phone"))
    );

    // 获取当前用户信息
    ClsMember clsMember = clsMemberMapper.selectClsMemberById(user.getId());
    // 变更缓存数据
    appTokenService.refreshToken(clsMember);

    return AjaxResult.success();
  }

  @PostMapping("/password/edit")
  public AjaxResult editPassword(@RequestBody JSONObject data) {
    // 获取当前登录用户
    AppLoginUser user = UserContextUtil.currentUser();

    String code = redisTemplate.opsForValue().get("sms_" + user.getPhone() + "_" + data.getString("code"));

    if (StringUtils.isBlank(code)) return AjaxResult.error("验证码错误");

    String password = SystemService.entryptPassword(data.getString("password"));
    // 变更手机号
    clsMemberMapper.update(null, new LambdaUpdateWrapper<ClsMember>()
            .eq(ClsMember::getId, user.getId())
            .set(ClsMember::getPassWord, password)
    );

    return AjaxResult.success();
  }

  /**
   * 修改会员设置信息
   *
   * @param
   * @return
   */
  @PostMapping(value = "/updateClsMember")
  @ApiOperation("更换绑定手机号")
  @ApiImplicitParams({
      @ApiImplicitParam(name = "phone", value = "修改登录密码", required = true),
      @ApiImplicitParam(name = "passWord", value = "修改登录密码", required = true),
  })
  @ApiIgnore
  public AjaxResult updateClsMember(String phone, String passWord) {
    List<ClsMember> umsMemberList = this.clsMemberMapper.selectClsMemberByPhone(phone);
    ClsMember vo = umsMemberList.get(0);
    vo.setPassWord(SystemService.entryptPassword(passWord));
    clsMemberMapper.updateClsMember(vo);
    return AjaxResult.success();
  }

  @GetMapping("/login/check")
  public AjaxResult checkLogin(HttpServletRequest request) {
    ClsMember appMember = appTokenService.getAppMember(request);
    return AjaxResult.success(appMember != null);
  }
}
